/*
 * jxSwing Project (2014)
 * 
 * by Denilson Edinaldo Pinto
 * 
 * LGPL
 * Copyright (C) 2014
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package org.jxSwing.component.panel;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.HeadlessException;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.beans.Transient;
import java.util.Vector;

import javax.swing.DefaultListCellRenderer;
import javax.swing.DropMode;
import javax.swing.JComponent;
import javax.swing.JList.DropLocation;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JViewport;
import javax.swing.ListCellRenderer;
import javax.swing.ListModel;
import javax.swing.ListSelectionModel;
import javax.swing.TransferHandler;
import javax.swing.UIManager;
import javax.swing.border.LineBorder;
import javax.swing.text.Position;

import org.jxSwing.component.JXComponent;
import org.jxSwing.component.list.List;
import org.jxSwing.i18n.I18N;
import org.jxUtils.check.CheckUtil;

/**
 * @author Denilson Edinaldo Pinto
 * @porject jxSwing
 * @package org.jxSwing.component.panel
 * @date 15/11/2014 - 21:16:22
 */
public class ListPanel<T> extends JPanel implements JXComponent {
	
	private static final long serialVersionUID = 3455821591748434422L;
	
	private JScrollPane scrollPane;
	
	private List<T> list;
	
	private boolean requiredBorderEnabled = true;
	
	/**
	 * 
	 */
	public ListPanel() {
	
		list = new List<T>();
		
		initGUI();
	}
	
	/**
	 * @param dataModel
	 */
	public ListPanel(ListModel<T> dataModel) {
	
		list = new List<T>(dataModel);
		
		initGUI();
	}
	
	/**
	 * @param listData
	 */
	public ListPanel(T[] listData) {
	
		list = new List<T>(listData);
		
		initGUI();
	}
	
	/**
	 * @param listData
	 */
	public ListPanel(Vector<? extends T> listData) {
	
		list = new List<T>(listData);
		
		initGUI();
	}
	
	/**
	 *
	 */
	private void initGUI() {
	
		getList().setRequiredBorderEnabled(false);
		
		setLayout(new BorderLayout());
		
		add(getScrollPane(), BorderLayout.CENTER);
	}
	
	/**
	 * Scrolls the list within an enclosing viewport to make the specified
	 * cell completely visible. This calls {@code scrollRectToVisible} with
	 * the bounds of the specified cell. For this method to work, the {@code JList} must be within a <code>JViewport</code>.
	 * <p>
	 * If the given index is outside the list's range of cells, this method results in nothing.
	 *
	 * @param index
	 *        the index of the cell to make visible
	 * @see JComponent#scrollRectToVisible
	 * @see #getVisibleRect
	 */
	public void ensureIndexIsVisible(int index) {
	
		getList().ensureIndexIsVisible(index);
	}
	
	/**
	 * Returns the bounding rectangle, in the list's coordinate system,
	 * for the range of cells specified by the two indices.
	 * These indices can be supplied in any order.
	 * <p>
	 * If the smaller index is outside the list's range of cells, this method returns {@code null}. If the smaller index is valid, but the larger index is outside the list's range, the bounds of just the first index is returned. Otherwise, the bounds of the valid range is returned.
	 * <p>
	 * This is a cover method that delegates to the method of the same name in the list's {@code ListUI}. It returns {@code null} if the list has no {@code ListUI}.
	 *
	 * @param index0
	 *        the first index in the range
	 * @param index1
	 *        the second index in the range
	 * @return the bounding rectangle for the range of cells, or {@code null}
	 */
	public Rectangle getCellBounds(int index0, int index1) {
	
		return getList().getCellBounds(index0, index1);
	}
	
	/**
	 * Returns the object responsible for painting list items.
	 *
	 * @return the value of the {@code cellRenderer} property
	 * @see #setCellRenderer
	 */
	@Transient
	public ListCellRenderer<? super T> getCellRenderer() {
	
		return getList().getCellRenderer();
	}
	
	/**
	 * Returns whether or not automatic drag handling is enabled.
	 *
	 * @return the value of the {@code dragEnabled} property
	 * @see #setDragEnabled
	 * @since 1.4
	 */
	public boolean getDragEnabled() {
	
		return getList().getDragEnabled();
	}
	
	/**
	 * Returns the location that this component should visually indicate
	 * as the drop location during a DnD operation over the component,
	 * or {@code null} if no location is to currently be shown.
	 * <p>
	 * This method is not meant for querying the drop location from a {@code TransferHandler}, as the drop location is only set after the {@code TransferHandler}'s <code>canImport</code> has returned and has allowed for the location to be shown.
	 * <p>
	 * When this property changes, a property change event with name "dropLocation" is fired by the component.
	 * <p>
	 * By default, responsibility for listening for changes to this property and indicating the drop location visually lies with the list's {@code ListUI}, which may paint it directly and/or install a cell renderer to do so. Developers wishing to implement custom drop location painting and/or replace the default cell renderer, may need to honor this property.
	 *
	 * @return the drop location
	 * @see #setDropMode
	 * @see TransferHandler#canImport(TransferHandler.TransferSupport)
	 * @since 1.6
	 */
	public final DropLocation getDropLocation() {
	
		return getList().getDropLocation();
	}
	
	/**
	 * Returns the drop mode for this component.
	 *
	 * @return the drop mode for this component
	 * @see #setDropMode
	 * @since 1.6
	 */
	public final DropMode getDropMode() {
	
		return getList().getDropMode();
	}
	
	/**
	 * Returns the smallest list index that is currently visible.
	 * In a left-to-right {@code componentOrientation}, the first visible
	 * cell is found closest to the list's upper-left corner. In right-to-left
	 * orientation, it is found closest to the upper-right corner.
	 * If nothing is visible or the list is empty, {@code -1} is returned.
	 * Note that the returned cell may only be partially visible.
	 *
	 * @return the index of the first visible cell
	 * @see #getLastVisibleIndex
	 * @see JComponent#getVisibleRect
	 */
	public int getFirstVisibleIndex() {
	
		return getList().getFirstVisibleIndex();
	}
	
	/**
	 * Returns the value of the {@code fixedCellHeight} property.
	 *
	 * @return the fixed cell height
	 * @see #setFixedCellHeight
	 */
	public int getFixedCellHeight() {
	
		return getList().getFixedCellHeight();
	}
	
	/**
	 * Returns the value of the {@code fixedCellWidth} property.
	 *
	 * @return the fixed cell width
	 * @see #setFixedCellWidth
	 */
	public int getFixedCellWidth() {
	
		return getList().getFixedCellWidth();
	}
	
	@Override
	public int getIndex() {
	
		return getList().getIndex();
	}
	
	/**
	 * Returns the largest list index that is currently visible.
	 * If nothing is visible or the list is empty, {@code -1} is returned.
	 * Note that the returned cell may only be partially visible.
	 *
	 * @return the index of the last visible cell
	 * @see #getFirstVisibleIndex
	 * @see JComponent#getVisibleRect
	 */
	public int getLastVisibleIndex() {
	
		return getList().getLastVisibleIndex();
	}
	
	/**
	 * Returns the layout orientation property for the list: {@code VERTICAL} if the layout is a single column of cells, {@code VERTICAL_WRAP} if the
	 * layout is "newspaper style" with the content flowing vertically then
	 * horizontally, or {@code HORIZONTAL_WRAP} if the layout is "newspaper
	 * style" with the content flowing horizontally then vertically.
	 *
	 * @return the value of the {@code layoutOrientation} property
	 * @see #setLayoutOrientation
	 * @since 1.4
	 */
	public int getLayoutOrientation() {
	
		return getList().getLayoutOrientation();
	}
	
	/**
	 * @return the list
	 */
	public final List<T> getList() {
	
		return list;
	}
	
	/**
	 * Returns the data model that holds the list of items displayed
	 * by the <code>JList</code> component.
	 *
	 * @return the <code>ListModel</code> that provides the displayed
	 *         list of items
	 * @see #setModel
	 */
	public ListModel<T> getModel() {
	
		return getList().getModel();
	}
	
	/**
	 * Returns the next list element whose {@code toString} value
	 * starts with the given prefix.
	 *
	 * @param prefix
	 *        the string to test for a match
	 * @param startIndex
	 *        the index for starting the search
	 * @param bias
	 *        the search direction, either
	 *        Position.Bias.Forward or Position.Bias.Backward.
	 * @return the index of the next list element that
	 *         starts with the prefix; otherwise {@code -1}
	 * @exception IllegalArgumentException
	 *            if prefix is {@code null} or startIndex is out of bounds
	 * @since 1.4
	 */
	public int getNextMatch(String prefix, int startIndex, Position.Bias bias) {
	
		return getList().getNextMatch(prefix, startIndex, bias);
	}
	
	/**
	 * Returns the "prototypical" cell value -- a value used to calculate a
	 * fixed width and height for cells. This can be {@code null} if there
	 * is no such value.
	 *
	 * @return the value of the {@code prototypeCellValue} property
	 * @see #setPrototypeCellValue
	 */
	public T getPrototypeCellValue() {
	
		return getList().getPrototypeCellValue();
	}
	
	/**
	 * @return the scrollPane
	 */
	public final JScrollPane getScrollPane() {
	
		if(scrollPane == null) {
			scrollPane = new JScrollPane(getList());
		}
		return scrollPane;
	}
	
	/**
	 * Returns the color used to draw the background of selected items. {@code DefaultListCellRenderer} uses this color to draw the background
	 * of items in the selected state, as do the renderers installed by most {@code ListUI} implementations.
	 *
	 * @return the color to draw the background of selected items
	 * @see #setSelectionBackground
	 * @see DefaultListCellRenderer
	 */
	public Color getSelectionBackground() {
	
		return getList().getSelectionBackground();
	}
	
	/**
	 * Returns the color used to draw the foreground of selected items. {@code DefaultListCellRenderer} uses this color to draw the foreground
	 * of items in the selected state, as do the renderers installed by most {@code ListUI} implementations.
	 *
	 * @return the color to draw the foreground of selected items
	 * @see #setSelectionForeground
	 * @see DefaultListCellRenderer
	 */
	public Color getSelectionForeground() {
	
		return getList().getSelectionForeground();
	}
	
	/**
	 * Returns the current selection model. The selection model maintains the
	 * selection state of the list. See the class level documentation for more
	 * details.
	 *
	 * @return the <code>ListSelectionModel</code> that maintains the
	 *         list's selections
	 * @see #setSelectionModel
	 * @see ListSelectionModel
	 */
	public ListSelectionModel getSelectionModel() {
	
		return getList().getSelectionModel();
	}
	
	/**
	 * Returns the tooltip text to be used for the given event. This overrides {@code JComponent}'s {@code getToolTipText} to first check the cell
	 * renderer component for the cell over which the event occurred, returning
	 * its tooltip text, if any. This implementation allows you to specify
	 * tooltip text on the cell level, by using {@code setToolTipText} on your
	 * cell renderer component.
	 * <p>
	 * <bold>Note:</bold> For <code>JList</code> to properly display the tooltips of its renderers in this manner, <code>JList</code> must be a registered component with the <code>ToolTipManager</code>. This registration is done automatically in the constructor. However, if at a later point <code>JList</code> is unregistered, by way of a call to {@code setToolTipText(null)}, tips from the renderers will no longer display.
	 *
	 * @param event
	 *        the {@code MouseEvent} to fetch the tooltip text for
	 * @see JComponent#setToolTipText
	 * @see JComponent#getToolTipText
	 */
	public String getToolTipText(MouseEvent event) {
	
		return getList().getToolTipText();
	}
	
	/**
	 * Returns the value of the {@code visibleRowCount} property. See the
	 * documentation for {@link #setVisibleRowCount} for details on how to
	 * interpret this value.
	 *
	 * @return the value of the {@code visibleRowCount} property.
	 * @see #setVisibleRowCount
	 */
	public int getVisibleRowCount() {
	
		return getList().getVisibleRowCount();
	}
	
	/**
	 * Returns the origin of the specified item in the list's coordinate
	 * system. This method returns {@code null} if the index isn't valid.
	 * <p>
	 * This is a cover method that delegates to the method of the same name in the list's {@code ListUI}. It returns {@code null} if the list has no {@code ListUI}.
	 *
	 * @param index
	 *        the cell index
	 * @return the origin of the cell, or {@code null}
	 */
	public Point indexToLocation(int index) {
	
		return getList().indexToLocation(index);
	}
	
	@Override
	public boolean isAtributte() {
	
		return getList().isAtributte();
	}
	
	@Override
	public boolean isRequired() {
	
		return getList().isRequired();
	}
	
	@Override
	public boolean isRequiredBorderEnabled() {
	
		return requiredBorderEnabled;
	}
	
	/**
	 * Returns the cell index closest to the given location in the list's
	 * coordinate system. To determine if the cell actually contains the
	 * specified location, compare the point against the cell's bounds,
	 * as provided by {@code getCellBounds}. This method returns {@code -1} if the model is empty
	 * <p>
	 * This is a cover method that delegates to the method of the same name in the list's {@code ListUI}. It returns {@code -1} if the list has no {@code ListUI}.
	 *
	 * @param location
	 *        the coordinates of the point
	 * @return the cell index closest to the given location, or {@code -1}
	 */
	public int locationToIndex(Point location) {
	
		return getList().locationToIndex(location);
	}
	
	@Override
	public void setAtributte(final boolean atributte) {
	
		getList().setAtributte(atributte);
	}
	
	/**
	 * Sets the delegate that is used to paint each cell in the list.
	 * The job of a cell renderer is discussed in detail in the
	 * <a href="#renderer">class level documentation</a>.
	 * <p>
	 * If the {@code prototypeCellValue} property is {@code non-null}, setting the cell renderer also causes the {@code fixedCellWidth} and {@code fixedCellHeight} properties to be re-calculated. Only one <code>PropertyChangeEvent</code> is generated however - for the <code>cellRenderer</code> property.
	 * <p>
	 * The default value of this property is provided by the {@code ListUI} delegate, i.e. by the look and feel implementation.
	 * <p>
	 * This is a JavaBeans bound property.
	 *
	 * @param cellRenderer
	 *        the <code>ListCellRenderer</code> that paints list cells
	 * @see #getCellRenderer
	 * @beaninfo
	 *           bound: true
	 *           attribute: visualUpdate true
	 *           description: The component used to draw the cells.
	 */
	public void setCellRenderer(ListCellRenderer<? super T> cellRenderer) {
	
		getList().setCellRenderer(cellRenderer);
	}
	
	/**
	 * Turns on or off automatic drag handling. In order to enable automatic
	 * drag handling, this property should be set to {@code true}, and the
	 * list's {@code TransferHandler} needs to be {@code non-null}.
	 * The default value of the {@code dragEnabled} property is {@code false}.
	 * <p>
	 * The job of honoring this property, and recognizing a user drag gesture, lies with the look and feel implementation, and in particular, the list's {@code ListUI}. When automatic drag handling is enabled, most look and feels (including those that subclass {@code BasicLookAndFeel}) begin a drag and drop operation whenever the user presses the mouse button over an item and then moves the mouse a few pixels. Setting this property to {@code true} can therefore have a subtle effect on how selections behave.
	 * <p>
	 * If a look and feel is used that ignores this property, you can still begin a drag and drop operation by calling {@code exportAsDrag} on the list's {@code TransferHandler}.
	 *
	 * @param b
	 *        whether or not to enable automatic drag handling
	 * @exception HeadlessException
	 *            if <code>b</code> is <code>true</code> and <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>
	 * @see java.awt.GraphicsEnvironment#isHeadless
	 * @see #getDragEnabled
	 * @see #setTransferHandler
	 * @see TransferHandler
	 * @since 1.4
	 * @beaninfo
	 *           description: determines whether automatic drag handling is enabled
	 *           bound: false
	 */
	public void setDragEnabled(boolean b) {
	
		getList().setDragEnabled(b);
	}
	
	/**
	 * Sets the drop mode for this component. For backward compatibility,
	 * the default for this property is <code>DropMode.USE_SELECTION</code>.
	 * Usage of one of the other modes is recommended, however, for an
	 * improved user experience. <code>DropMode.ON</code>, for instance,
	 * offers similar behavior of showing items as selected, but does so without
	 * affecting the actual selection in the list.
	 * <p>
	 * <code>JList</code> supports the following drop modes:
	 * <ul>
	 * <li><code>DropMode.USE_SELECTION</code></li>
	 * <li><code>DropMode.ON</code></li>
	 * <li><code>DropMode.INSERT</code></li>
	 * <li><code>DropMode.ON_OR_INSERT</code></li>
	 * </ul>
	 * The drop mode is only meaningful if this component has a <code>TransferHandler</code> that accepts drops.
	 *
	 * @param dropMode
	 *        the drop mode to use
	 * @throws IllegalArgumentException
	 *         if the drop mode is unsupported
	 *         or <code>null</code>
	 * @see #getDropMode
	 * @see #getDropLocation
	 * @see #setTransferHandler
	 * @see TransferHandler
	 * @since 1.6
	 */
	public final void setDropMode(DropMode dropMode) {
	
		getList().setDropMode(dropMode);
	}
	
	/**
	 * Sets a fixed value to be used for the height of every cell in the list.
	 * If {@code height} is -1, cell heights are computed in the {@code ListUI} by applying <code>getPreferredSize</code> to the cell renderer component
	 * for each list element.
	 * <p>
	 * The default value of this property is {@code -1}.
	 * <p>
	 * This is a JavaBeans bound property.
	 *
	 * @param height
	 *        the height to be used for for all cells in the list
	 * @see #setPrototypeCellValue
	 * @see #setFixedCellWidth
	 * @see JComponent#addPropertyChangeListener
	 * @beaninfo
	 *           bound: true
	 *           attribute: visualUpdate true
	 *           description: Defines a fixed cell height when greater than zero.
	 */
	public void setFixedCellHeight(int height) {
	
		getList().setFixedCellHeight(height);
	}
	
	/**
	 * Sets a fixed value to be used for the width of every cell in the list.
	 * If {@code width} is -1, cell widths are computed in the {@code ListUI} by applying <code>getPreferredSize</code> to the cell renderer component
	 * for each list element.
	 * <p>
	 * The default value of this property is {@code -1}.
	 * <p>
	 * This is a JavaBeans bound property.
	 *
	 * @param width
	 *        the width to be used for all cells in the list
	 * @see #setPrototypeCellValue
	 * @see #setFixedCellWidth
	 * @see JComponent#addPropertyChangeListener
	 * @beaninfo
	 *           bound: true
	 *           attribute: visualUpdate true
	 *           description: Defines a fixed cell width when greater than zero.
	 */
	public void setFixedCellWidth(int width) {
	
		getList().setFixedCellWidth(width);
	}
	
	@Override
	public void setIndex(final int index) {
	
		getList().setIndex(index);
	}
	
	/**
	 * Defines the way list cells are layed out. Consider a {@code JList} with five cells. Cells can be layed out in one of the following ways:
	 * <p>
	 * 
	 * <pre>
	 * VERTICAL:          0
	 *                    1
	 *                    2
	 *                    3
	 *                    4
	 * 
	 * HORIZONTAL_WRAP:   0  1  2
	 *                    3  4
	 * 
	 * VERTICAL_WRAP:     0  3
	 *                    1  4
	 *                    2
	 * </pre>
	 * <p>
	 * A description of these layouts follows:
	 * <table border="1" * summary="Describes layouts VERTICAL, HORIZONTAL_WRAP, and VERTICAL_WRAP">
	 * <tr>
	 * <th>
	 * <p align="left">
	 * Value
	 * </p>
	 * </th>
	 * <th>
	 * <p align="left">
	 * Description
	 * </p>
	 * </th>
	 * </tr>
	 * <tr>
	 * <td><code>VERTICAL</code>
	 * <td>Cells are layed out vertically in a single column.
	 * <tr>
	 * <td><code>HORIZONTAL_WRAP</code>
	 * <td>Cells are layed out horizontally, wrapping to a new row as necessary. If the {@code visibleRowCount} property is less than or equal to zero, wrapping is determined by the width of the list; otherwise wrapping is done in such a way as to ensure {@code visibleRowCount} rows in the list.
	 * <tr>
	 * <td><code>VERTICAL_WRAP</code>
	 * <td>Cells are layed out vertically, wrapping to a new column as necessary. If the {@code visibleRowCount} property is less than or equal to zero, wrapping is determined by the height of the list; otherwise wrapping is done at {@code visibleRowCount} rows.
	 * </table>
	 * <p>
	 * The default value of this property is <code>VERTICAL</code>.
	 *
	 * @param layoutOrientation
	 *        the new layout orientation, one of: {@code VERTICAL}, {@code HORIZONTAL_WRAP} or {@code VERTICAL_WRAP}
	 * @see #getLayoutOrientation
	 * @see #setVisibleRowCount
	 * @see #getScrollableTracksViewportHeight
	 * @see #getScrollableTracksViewportWidth
	 * @throws IllegalArgumentException
	 *         if {@code layoutOrientation} isn't one of the
	 *         allowable values
	 * @since 1.4
	 * @beaninfo
	 *           bound: true
	 *           attribute: visualUpdate true
	 *           description: Defines the way list cells are layed out.
	 *           enum: VERTICAL JList.VERTICAL
	 *           HORIZONTAL_WRAP JList.HORIZONTAL_WRAP
	 *           VERTICAL_WRAP JList.VERTICAL_WRAP
	 */
	public void setLayoutOrientation(int layoutOrientation) {
	
		getList().setLayoutOrientation(layoutOrientation);
	}
	
	/**
	 * Constructs a read-only <code>ListModel</code> from an array of items,
	 * and calls {@code setModel} with this model.
	 * <p>
	 * Attempts to pass a {@code null} value to this method results in undefined behavior and, most likely, exceptions. The created model references the given array directly. Attempts to modify the array after invoking this method results in undefined behavior.
	 *
	 * @param listData
	 *        an array of {@code T} containing the items to
	 *        display in the list
	 * @see #setModel
	 */
	public void setListData(final T[] listData) {
	
		getList().setListData(listData);
	}
	
	/**
	 * Constructs a read-only <code>ListModel</code> from a <code>Vector</code> and calls {@code setModel} with this model.
	 * <p>
	 * Attempts to pass a {@code null} value to this method results in undefined behavior and, most likely, exceptions. The created model references the given {@code Vector} directly. Attempts to modify the {@code Vector} after invoking this method results in undefined behavior.
	 *
	 * @param listData
	 *        a <code>Vector</code> containing the items to
	 *        display in the list
	 * @see #setModel
	 */
	public void setListData(final Vector<? extends T> listData) {
	
		getList().setListData(listData);
	}
	
	/**
	 * Sets the model that represents the contents or "value" of the
	 * list, notifies property change listeners, and then clears the
	 * list's selection.
	 * <p>
	 * This is a JavaBeans bound property.
	 *
	 * @param model
	 *        the <code>ListModel</code> that provides the
	 *        list of items for display
	 * @exception IllegalArgumentException
	 *            if <code>model</code> is <code>null</code>
	 * @see #getModel
	 * @see #clearSelection
	 * @beaninfo
	 *           bound: true
	 *           attribute: visualUpdate true
	 *           description: The object that contains the data to be drawn by this JList.
	 */
	public void setModel(ListModel<T> model) {
	
		getList().setModel(model);
	}
	
	@Override
	public void setName(final String name) {
	
		super.setName(name);
		
		getList().setName(name);
		
		setRequired(isRequired());
	}
	
	/**
	 * Sets the {@code prototypeCellValue} property, and then (if the new value
	 * is {@code non-null}), computes the {@code fixedCellWidth} and {@code fixedCellHeight} properties by requesting the cell renderer
	 * component for the given value (and index 0) from the cell renderer, and
	 * using that component's preferred size.
	 * <p>
	 * This method is useful when the list is too long to allow the {@code ListUI} to compute the width/height of each cell, and there is a single cell value that is known to occupy as much space as any of the others, a so-called prototype.
	 * <p>
	 * While all three of the {@code prototypeCellValue}, {@code fixedCellHeight}, and {@code fixedCellWidth} properties may be modified by this method, {@code PropertyChangeEvent} notifications are only sent when the {@code prototypeCellValue} property changes.
	 * <p>
	 * To see an example which sets this property, see the <a href="#prototype_example">class description</a> above.
	 * <p>
	 * The default value of this property is <code>null</code>.
	 * <p>
	 * This is a JavaBeans bound property.
	 *
	 * @param prototypeCellValue
	 *        the value on which to base <code>fixedCellWidth</code> and <code>fixedCellHeight</code>
	 * @see #getPrototypeCellValue
	 * @see #setFixedCellWidth
	 * @see #setFixedCellHeight
	 * @see JComponent#addPropertyChangeListener
	 * @beaninfo
	 *           bound: true
	 *           attribute: visualUpdate true
	 *           description: The cell prototype value, used to compute cell width and height.
	 */
	public void setPrototypeCellValue(T prototypeCellValue) {
	
		getList().setPrototypeCellValue(prototypeCellValue);
	}
	
	@Override
	public void setRequired(final boolean required) {
	
		getList().setRequired(required);
		
		//
		if(required) {
			
			//
			if(isRequiredBorderEnabled()) {
				
				setBorder(new LineBorder(Color.RED));
			}
			
			//
			if(CheckUtil.isNullOrAbsoluteEmpty(getName())) {
				
				setToolTipText(I18N.component().requiredThis());
				
			}else {
				
				setToolTipText(I18N.component().requiredField(getName()));
			}
			
		}else {
			
			setBorder(UIManager.getBorder("Panel.border"));
			setToolTipText(null);
		}
	}
	
	@Override
	public void setRequiredBorderEnabled(final boolean requiredBorderEnabled) {
	
		this.requiredBorderEnabled = requiredBorderEnabled;
	}
	
	/**
	 * Sets the color used to draw the background of selected items, which
	 * cell renderers can use fill selected cells. {@code DefaultListCellRenderer} uses this color to fill the background
	 * of items in the selected state, as do the renderers installed by most {@code ListUI} implementations.
	 * <p>
	 * The default value of this property is defined by the look and feel implementation.
	 * <p>
	 * This is a JavaBeans bound property.
	 *
	 * @param selectionBackground
	 *        the {@code Color} to use for the
	 *        background of selected cells
	 * @see #getSelectionBackground
	 * @see #setSelectionForeground
	 * @see #setForeground
	 * @see #setBackground
	 * @see #setFont
	 * @see DefaultListCellRenderer
	 * @beaninfo
	 *           bound: true
	 *           attribute: visualUpdate true
	 *           description: The background color of selected cells.
	 */
	public void setSelectionBackground(Color selectionBackground) {
	
		getList().setSelectionBackground(selectionBackground);
	}
	
	/**
	 * Sets the color used to draw the foreground of selected items, which
	 * cell renderers can use to render text and graphics. {@code DefaultListCellRenderer} uses this color to draw the foreground
	 * of items in the selected state, as do the renderers installed by most {@code ListUI} implementations.
	 * <p>
	 * The default value of this property is defined by the look and feel implementation.
	 * <p>
	 * This is a JavaBeans bound property.
	 *
	 * @param selectionForeground
	 *        the {@code Color} to use in the foreground
	 *        for selected list items
	 * @see #getSelectionForeground
	 * @see #setSelectionBackground
	 * @see #setForeground
	 * @see #setBackground
	 * @see #setFont
	 * @see DefaultListCellRenderer
	 * @beaninfo
	 *           bound: true
	 *           attribute: visualUpdate true
	 *           description: The foreground color of selected cells.
	 */
	public void setSelectionForeground(Color selectionForeground) {
	
		getList().setSelectionForeground(selectionForeground);
	}
	
	/**
	 * Sets the {@code visibleRowCount} property, which has different meanings
	 * depending on the layout orientation: For a {@code VERTICAL} layout
	 * orientation, this sets the preferred number of rows to display without
	 * requiring scrolling; for other orientations, it affects the wrapping of
	 * cells.
	 * <p>
	 * In {@code VERTICAL} orientation:<br>
	 * Setting this property affects the return value of the {@link #getPreferredScrollableViewportSize} method, which is used to calculate the preferred size of an enclosing viewport. See that method's documentation for more details.
	 * <p>
	 * In {@code HORIZONTAL_WRAP} and {@code VERTICAL_WRAP} orientations:<br>
	 * This affects how cells are wrapped. See the documentation of {@link #setLayoutOrientation} for more details.
	 * <p>
	 * The default value of this property is {@code 8}.
	 * <p>
	 * Calling this method with a negative value results in the property being set to {@code 0}.
	 * <p>
	 * This is a JavaBeans bound property.
	 *
	 * @param visibleRowCount
	 *        an integer specifying the preferred number of
	 *        rows to display without requiring scrolling
	 * @see #getVisibleRowCount
	 * @see #getPreferredScrollableViewportSize
	 * @see #setLayoutOrientation
	 * @see JComponent#getVisibleRect
	 * @see JViewport
	 * @beaninfo
	 *           bound: true
	 *           attribute: visualUpdate true
	 *           description: The preferred number of rows to display without
	 *           requiring scrolling
	 */
	public void setVisibleRowCount(int visibleRowCount) {
	
		getList().setVisibleRowCount(visibleRowCount);
	}
}
